package com.example.complier;


import com.example.annotations.Skill;
import com.google.auto.service.AutoService;

import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Filer;
import javax.annotation.processing.Messager;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.Processor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;

/**
 * @author: fuchenming
 * @create: 2019-08-20 08:28
 */
@SupportedSourceVersion(SourceVersion.RELEASE_7)
@AutoService(Processor.class)
public class SkillProcessor extends AbstractProcessor {
    private Filer mFiler;
    private Messager messager;
    private static StringBuilder builder;
    private static String newClassName = "SkillMap" + System.currentTimeMillis();

    @Override
    public synchronized void init(ProcessingEnvironment processingEnvironment) {
        super.init(processingEnvironment);
        mFiler = processingEnv.getFiler();
        messager = processingEnvironment.getMessager();
    }

    @Override
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.RELEASE_7;
    }

    @Override
    public Set<String> getSupportedAnnotationTypes() {
        Set<String> annotations = new LinkedHashSet<>();
        annotations.add(Skill.class.getCanonicalName());
//        annotations.add("com.hongx.compiler.annotation.Skill");
        return annotations;
    }

    @Override
    public synchronized boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
        messager.printMessage(Diagnostic.Kind.NOTE, "log process start---------------" + roundEnvironment.toString());
        Set<? extends Element> SkillElements = roundEnvironment.getElementsAnnotatedWith(Skill.class);
        if (SkillElements == null || SkillElements.size() == 0) {
            return true;
        }
        builder = new StringBuilder()
                .append("package com.example.app.skills;\n\n")
                .append("import java.util.HashMap;\n")
                .append("import com.example.base.BaseApp;\n")
                .append("import com.example.base.SkillManager;\n\n")
                .append("public class ")
                .append(newClassName)
                .append(" {\n\n") // open class
//                .append("\tpublic static HashMap<String, SkillManager> map = new HashMap<>();\n") //
//                .append("\tpublic static void initMap() throws Exception{\n"); // open method
                .append("static {\n");
        for (Element element : SkillElements) {
            Skill Skill = element.getAnnotation(Skill.class);
            String intent = Skill.intent();
            if (element instanceof TypeElement) {
                TypeElement te = (TypeElement) element;
//                builder.append("\t\tmap.put(\"" + intent + "\", " + te.getQualifiedName().toString() + ".class.newInstance());\n");
                builder.append("\t\tBaseApp.addSkill(\"" + intent + "\", " + te.getQualifiedName().toString() + ".class);\n");
            }
        }
        builder.append("}\n") // close method
                .append("}\n"); // close class
        System.out.println(builder.toString());
        try {
            JavaFileObject source = mFiler.createSourceFile("com.example.app.skills." + newClassName);
            Writer writer = source.openWriter();
            writer.write(builder.toString());
            writer.flush();
            writer.close();
        } catch (IOException e) {
        }
        return false;
    }
}

